package com.auto.admin.service;

import com.alibaba.fastjson.JSONObject;
import com.auto.admin.entity.ApiInfo;
import com.auto.admin.entity.ParamMapping;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author liangshf
 * @Description: 基础抽象调用服务
 * @date 2018-06-20
 */
public abstract class AbstractMockService {
	private static Logger logger = LoggerFactory
			.getLogger(AbstractMockService.class);

	@Resource
	ApiInfoService apiInfoService;

	@Resource
  ParamMappingService paramMappingService;

	
	public ApiInfo getControllerUrlMapping(Long urlId){
		return apiInfoService.getById(urlId);
	}
	

	
	public Map<String, Object> getParamMap(ApiInfo controllerUrlMapping, Map<String, Object> tabKeyMap){
		String[] params = controllerUrlMapping.getArgs().split(",");
		String attr ;
		Map<String, Object> newMap = Maps.newHashMap();
		if (params.length == 1) {
			attr = params[0];
			newMap = getParamMap( attr, controllerUrlMapping, tabKeyMap);
		} else if (params.length > 1) {
			for (String attrs : params) {
				newMap.putAll(getParamMap( attrs, controllerUrlMapping, tabKeyMap));
			}
		}
		return newMap;
	}
	
	private Map<String, Object> getParamMap(String attr, ApiInfo controllerUrlMapping, Map<String, Object> tabKeyMap) {
		String[] attrs = attr.split("=");
		String attrName = attrs[0];
		String attrValue = attrs[1];

		List<ParamMapping> paramMappings = paramMappingService
				.findByUrlId(controllerUrlMapping.getId());
		Map<String, List<ParamMapping>> paramMappingsMap = paramMappings
				.stream().collect(
						Collectors.groupingBy(ParamMapping::getFullAttrName));
		Map<String, Object> newMap = Maps.newHashMap();
		if (attrValue.equals("java.util.List")
				|| attrValue.equals("java.lang.Long")
				|| attrValue.equals("java.lang.String")
				|| attrValue.equals("java.util.Collection")
				|| attrValue.equals("java.lang.Integer")) {
			//System.out.println("基础类型查询处理");
			newMap.put(attrName, tabKeyMap.get(attrName));
		} else {
			// autoParamJson 转map
			Map<String,Object> map = JSONObject.parseObject(controllerUrlMapping.getAutoParamJson(),Map.class);
			for (String key : map.keySet()) {
				String propertyName ;
				String propertyFullName ;
				if(key.indexOf("-") != -1){
					propertyName = key.split("-")[0];
					propertyFullName = key.split("-")[1];
				}else {
					propertyName = key;
					propertyFullName = key;
				}
				Object object = map.get(key);
				if(tabKeyMap.containsKey(propertyFullName)){
					newMap.put(propertyName, tabKeyMap.get(propertyFullName));
				}else if(object instanceof List){
					setListMapValue(tabKeyMap, paramMappingsMap, newMap, propertyName, propertyFullName,
							object); 
				} else {
					setValue(paramMappingsMap, newMap, propertyName, propertyFullName, object, tabKeyMap);
				}
			}
		}
		return newMap;
	}
	@SuppressWarnings("unchecked")
	private void setListMapValue(Map<String, Object> tabKeyMap,
			Map<String, List<ParamMapping>> paramMappingsMap,
			Map<String, Object> newMap, String propertyName, String propertyFullName, Object object) {
		List<Object> list =(List<Object>)object;
		Object listO = list.get(0);
		List<Object> result1 =Lists.newArrayList();
		if (listO instanceof Map) {
			Map<String, Object> newleMap = Maps.newHashMap();
			
			Map<String, Object> leMap = (Map<String, Object>) listO;

			for (String leKey : leMap.keySet()) {
				String lePropertyName ;
				String lePropertyFullName ;
				if(leKey.indexOf("-") != -1){
					lePropertyName = leKey.split("-")[0];
					lePropertyFullName = leKey.split("-")[1];
				}else {
					lePropertyName = leKey;
					lePropertyFullName = leKey;
				}
				Object o2 = leMap.get(leKey);
				if(o2 instanceof List){
					List<Object> list2 =(List<Object>)o2;
					Object list2O = list2.get(0);
					if(tabKeyMap.containsKey(lePropertyName)){
						newleMap.put(lePropertyName, tabKeyMap.get(lePropertyName));
					}else if (list2O instanceof Map) {
						setListMapValue(tabKeyMap, paramMappingsMap, newleMap, lePropertyName, lePropertyFullName, o2);
					}else {
						newleMap.put(lePropertyName, Arrays.asList(1));
					}
				}else {
					setValue(paramMappingsMap, newleMap, lePropertyName, lePropertyFullName, o2, tabKeyMap);
				}
			}
			result1.add(newleMap);
			if(tabKeyMap.containsKey(propertyName)){
				newleMap.put(propertyName, tabKeyMap.get(propertyName));
			}else {
				newMap.put(propertyName, result1);
			}
		}else {
			setValue(paramMappingsMap, newMap, propertyName, propertyFullName, object, tabKeyMap);
		}
	}

	private void setValue(Map<String, List<ParamMapping>> paramMappingsMap,
			Map<String, Object> newleMap, String propertyName, String propertyFullName, Object o, Map<String, Object> tabKeyMap) {
		ParamMapping paramMapping;
		List<ParamMapping> list = paramMappingsMap.get(propertyFullName);
		if (list != null) {
			paramMapping = list.get(0);
			if(paramMapping.getSourceType() == null) return;
			if (paramMapping.getSourceType() == 1) {

				if (paramMapping.getAttrType().equals("List,java.lang.String")
						|| paramMapping.getAttrType().equals(
								"List,java.lang.Long")) {
					List<String> list2 = Lists.newArrayList();
					list2.add(paramMapping.getDicValues());
					newleMap.put(propertyName, list2);
				} else if (paramMapping.getAttrType().equals(
						"Set,java.lang.Long")) {
					Set<String> set = new HashSet<String>();
					set.add(paramMapping.getDicValues());
					newleMap.put(propertyName, set);
				} else {
					newleMap.put(propertyName, paramMapping.getDicValues());
				}

			} else if (paramMapping.getSourceType() == 2) {
				String[] values = paramMapping.getDicValues().split(",");
				int index = (int) (Math.random() * values.length);
				newleMap.put(propertyName, values[index]);
			} else if (paramMapping.getSourceType() == 3) {
				if (paramMapping.getAttrType().equals("Long")
						|| paramMapping.getAttrType().equals(
								"Integer")) {
					Object tableValue = tabKeyMap.get(propertyFullName);
					if(tableValue != null) {
						newleMap.put(propertyName, tableValue);
					}else {
						newleMap.put(propertyName,
								(int) (1 + Math.random() * (10 - 1 + 1)));
					}
				}else if (paramMapping.getAttrType().equals("List,java.lang.String")
						|| paramMapping.getAttrType().equals(
								"List,java.lang.Long")) {
					Object tableValue = tabKeyMap.get(propertyFullName);
					if(tableValue != null) {
						newleMap.put(propertyName, tableValue);
					}else {
						List<Object> list2 = Lists.newArrayList();
						list2.add(paramMapping.getDicValues());
						newleMap.put(propertyName, list2);
					}
				} else if (paramMapping.getAttrType().equals(
						"Set,java.lang.Long")) {
					Object tableValue = tabKeyMap.get(propertyFullName);
					if(tableValue != null) {
						newleMap.put(propertyName, tableValue);
					}else {
						Set<Object> set = new HashSet<Object>();
						set.add(paramMapping.getDicValues());
						newleMap.put(propertyName, set);
					}
				}else {
					Object tableValue = tabKeyMap.get(propertyFullName);
					if(tableValue != null) {
						newleMap.put(propertyName, tableValue);
					}
				}

			} else if (paramMapping.getSourceType() == 4) {
				if (paramMapping.getAttrType().equals("Long")
						|| paramMapping.getAttrType().equals(
								"Integer")) {
					newleMap.put(propertyName,
							(int) (1 + Math.random() * (10 - 1 + 1)));
				} else {
					newleMap.put(propertyName,
							RandomStringUtils.randomAlphanumeric(10));
				}
			}
		} else {
			Object tableValue = tabKeyMap.get(propertyFullName);
			if(tableValue != null) {
				newleMap.put(propertyName, tableValue);
			}else {
				newleMap.put(propertyName, o);
			}
		}
	}

}
